package com.gs.zsmanage.config.datasource;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


/**
 * Created with IntelliJ IDEA.
 * User: Legolas
 * Date: 2017/7/17 0017
 */

@Component
public class DataSourceAspect {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    public void before(JoinPoint point) throws Exception {
        Class<?> target = point.getTarget().getClass();
        MethodSignature signature = (MethodSignature) point.getSignature();
        // 使用目标注解类型，如果没有，则使用其接口指定类型
        for (Class<?> clazz : target.getInterfaces()) {
            resolveDataSource(clazz, signature.getMethod());
        }
        resolveDataSource(target, signature.getMethod());
    }

    /**
     * 获取目标对象方法注解和类型注解中的注解
     */
    private void resolveDataSource(Class<?> clazz, Method method) {
        try {
            Class<?>[] types = method.getParameterTypes();
            // 默认使用类型注解
            if (clazz.isAnnotationPresent(TargetDataSource.class)) {
                TargetDataSource cds = clazz.getAnnotation(TargetDataSource.class);
                DataSourceContextHolder.setDS(cds.value());
            }
            // 方法注解覆盖，以方法注解为最后值
            Method m = clazz.getMethod(method.getName(), types);
            if (m != null && m.isAnnotationPresent(TargetDataSource.class)) {
                TargetDataSource cds = m.getAnnotation(TargetDataSource.class);
                DataSourceContextHolder.setDS(cds.value());
            }
        } catch (Exception e) {
            logger.error(clazz + ":" + e.getMessage());
        }
    }

    public void after(JoinPoint point) throws Exception {
        DataSourceContextHolder.clearDS();
    }


    /*

       public void setDataSource1(JoinPoint point) {
            DataSourceContextHolder.setDS(DatasourceKey.legolas1);
        }

        public void setDataSource2(JoinPoint point) {
            DataSourceContextHolder.setDS(DatasourceKey.legolas2);
        }

    */


}